package com.yindian.cos.monitor.core;

import com.yindian.cos.logging.elastic.LogOutputObject;
import com.yindian.cos.monitor.model.Tracker;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Map;

/**
 * 自定义tracker扩展类
 *
 * @author zhangchuanhao
 * @create 2018/12/26
 */
@Log4j2
public class LogOutputObjectImpl implements LogOutputObject {

    @Override
    public Map<String, Object> outPutObject(Map<String, Object> source) {
        return trackerCovertMap(source);
    }

    @Override
    public boolean isOutput(Map<String, Object> source) {
        return source.containsKey("trackerId");
    }


    /**
     * 将tracker转换为map返回
     *
     * @param source
     * @return
     */
    private Map<String, Object> trackerCovertMap(Map<String, Object> source) {
        if (source != null) {
            Object object = source.get("contextMap");
            if (object != null) {
                Map contextMap = (Map) object;
                if (contextMap.containsKey(TrackerService.TRACKER)) {
                    String trackerJson = (String) contextMap.get(TrackerService.TRACKER);
                    if (StringUtils.isNotBlank(trackerJson)) {
                        try {
                            Tracker tracker = TrackerService.objectMapper.readValue(trackerJson, Tracker.class);
                            Field[] fields = tracker.getClass().getDeclaredFields();
                            for (Field field : fields) {
                                String fieldName = field.getName();
                                Object value = getValue(tracker, fieldName);
                                if (value != null) {
                                    source.put(fieldName, value);
                                }
                            }
                        } catch (IOException e) {
                            log.error("jackson转换json失败，{}", e);
                        }
                    }
                    source.remove("contextMap");
                }
            }
        }
        return source;
    }

    /**
     * 根据反射获取方法的值
     *
     * @param source 目标对象
     * @param field  属性名称
     * @return
     */
    private static Object getValue(Object source, String field) {
        String methodName = "get" + firstLetterCapitalize(field);
        try {
            return source.getClass().getDeclaredMethod(methodName).invoke(source);
        } catch (Exception e) {
            log.error("get方法获取属性值失败，method = {}，exception = {}", methodName, e);
        }
        return null;
    }


    /**
     * 首字母大写
     *
     * @param field
     * @return
     */
    private static String firstLetterCapitalize(String field) {
        return field.substring(0, 1).toUpperCase() + field.substring(1);
    }
}
